﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace MediaPlayer
{
	public partial class MainWindow : Window
	{

        DispatcherTimer seekTimer;
        DispatcherTimer curentPositionTimer;
        DispatcherTimer hidePlayControlsTimer;

        private double mediaPlayerWidth;
        private double mediaPlayerHeight;
        private Brush gridMediaPlayerBackground;
        private Thickness myMediaElementMargin;
       
        private bool isDragging;
        private bool isPlaying=false;
        private bool isPaused=false;
        private bool isFullscreen=false;
        private bool isMuted = false;

        private string filesource;



		public MainWindow()
		{
			this.InitializeComponent();
            InitializeTimers();
            Subscribe();
            LoadSetings();
		}

        private void LoadSetings()
        {
            volumeSlider.Value = UserSettings.Volume;
            VolumeSliderDragCompleted(this, null);    
        }

        private void SaveSetings()
        {
            UserSettings.Volume = (int)volumeSlider.Value;
        }

        private void InitializeTimers()
        {
            seekTimer = new DispatcherTimer();
            seekTimer.Interval = TimeSpan.FromMilliseconds(200);

            curentPositionTimer = new DispatcherTimer();
            curentPositionTimer.Interval = TimeSpan.FromSeconds(1);
            curentPositionTimer.Tick += new EventHandler(curentPositionTimer_Tick);

            hidePlayControlsTimer = new DispatcherTimer();
            hidePlayControlsTimer.Interval = TimeSpan.FromSeconds(5);
            hidePlayControlsTimer.Tick += hidePlayControlsTimer_Tick;
        }

        void hidePlayControlsTimer_Tick(object sender, EventArgs e)
        {
            HidePlayControls();
        }
       
        public void Subscribe()
        {
            MediaPlayerUserControl.OpenFileButtonClicked += OpenFile;
            MediaPlayerUserControl.PlayButtonClicked += Play;
            MediaPlayerUserControl.PauseButtonClicked += Play;
            MediaPlayerUserControl.StopButtonClicked += Stop;
            MediaPlayerUserControl.FastForwardButtonClicked += FastForward;
            MediaPlayerUserControl.RewindButtonClicked += Rewind;
            MediaPlayerUserControl.FullScreenButtonClicked += Fullscreen;
            MediaPlayerUserControl.OpenStreamButtonClicked += MediaPlayerUserControl_OpenStreamButtonClicked;

            seekTimer.Tick += seekTimer_Tick;
        }

        void MediaPlayerUserControl_OpenStreamButtonClicked()
        {
            OpenUrlWindow();
        }

        private void OpenUrlWindow()
        {
            string urlString;

            urlWindow window = new urlWindow();
            window.ShowDialog();
            urlString = window.UrlWindowResault;

            if (!urlString.Equals(""))
            {
                filesource = urlString;
                Stop();
                Play();
            }
        }

        void curentPositionTimer_Tick(object sender, EventArgs e)
        {
            SetCurrentDuration();
        }

        void seekTimer_Tick(object sender, EventArgs e)
        {
            if (!isDragging)
            {
                seekSlider.Value = MyMediaElement.Position.TotalSeconds;
            }
        }

        private void OpenFile()
        {
            Microsoft.Win32.OpenFileDialog openFile = new Microsoft.Win32.OpenFileDialog();
            openFile.FileName = "Video file";
            openFile.DefaultExt = ".avi";
            openFile.Filter = "Video File (.avi)|*.*";

            Nullable<bool> result = openFile.ShowDialog();
            if (result == true)
            {
                filesource = openFile.FileName;
                Stop();
                Play();
            }
        }

        //play/Pause 
        private void Play()
        {
            if (!isPlaying)
            {
                if (!isPaused)
                {
                    try
                    {
                        MyMediaElement.Source = new Uri(filesource);
                        MyMediaElement.Play();
                        isPlaying = true;
                        MediaBorder.Visibility = System.Windows.Visibility.Hidden;
                        curentPositionTimer.Start();
                        SetDuration();
                        SetWindowTitle();
                        MediaPlayerUserControl.pauseButton.Visibility = Visibility.Visible;
                        MediaPlayerUserControl.playButton.Visibility = Visibility.Hidden;
                        menuItemPlay.IsEnabled = false;
                        menuItemPause.IsEnabled = true;
                    }
                    catch (Exception e)
                    {
                        if (MyMediaElement.Source == null)
                        {
                             MessageBox.Show("Open file !!!");
                        }
                    }
                }
                else
                {
                    MyMediaElement.Play();
                    SetWindowTitle();
                    isPlaying = true;
                    isPaused = false;
                    MediaPlayerUserControl.pauseButton.Visibility = Visibility.Visible;
                    MediaPlayerUserControl.playButton.Visibility = Visibility.Hidden;
                    menuItemPlay.IsEnabled = false;
                    menuItemPause.IsEnabled = true;
                }
            }
            else
            {
                MyMediaElement.Pause();
                isPlaying = false;
                isPaused = true;
                MediaPlayerUserControl.pauseButton.Visibility = Visibility.Hidden;
                MediaPlayerUserControl.playButton.Visibility = Visibility.Visible;
                menuItemPlay.IsEnabled = true; ;
                menuItemPause.IsEnabled = false;
            }
        }
       
        private void Stop()
        {
            MyMediaElement.Stop();
            curentPositionTimer.Stop();
            isPlaying = false;
            isPaused = false;
            MediaBorder.Visibility = System.Windows.Visibility.Visible;
            ResetDurationCounters();
            Window.Title = "Media Player";
            MediaPlayerUserControl.pauseButton.Visibility = Visibility.Hidden;
            MediaPlayerUserControl.playButton.Visibility = Visibility.Visible;
            menuItemPlay.IsEnabled = true;
            menuItemPause.IsEnabled = false;
            ShowPlayControls();
        }

        private void FastForward(object sender, EventArgs e)
        {
            seekSliderDragStarted(this, e);
            seekSlider.Value += 20;
            seekSliderDragCompleted(this, e);
        }

        private void Rewind(object sender, EventArgs e)
        {
            seekSliderDragStarted(this, e);
            seekSlider.Value -= 20;
            seekSliderDragCompleted(this, e);
        }

        private void MyMediaElement_MediaOpened(object sender, System.Windows.RoutedEventArgs e)
        {
            if (MyMediaElement.NaturalDuration.HasTimeSpan)
            {
                TimeSpan timeSpan = MyMediaElement.NaturalDuration.TimeSpan;
                seekSlider.Maximum = timeSpan.TotalSeconds;
                seekSlider.SmallChange = 1;
                seekSlider.LargeChange = Math.Min(10, timeSpan.Seconds / 10);
            }
            seekTimer.Start();
            SetDuration();
            SetWindowTitle();
            MediaPlayerUserControl.pauseButton.Visibility = Visibility.Visible;
            MediaPlayerUserControl.playButton.Visibility = Visibility.Hidden;
            menuItemPlay.IsEnabled = false;
            menuItemPause.IsEnabled = true;
        }

        private void seekSliderDragStarted(object sender, EventArgs e)
        {
            isDragging = true;
        }

        private void seekSliderDragCompleted(object sender, EventArgs e)
        {
            isDragging = false;
            MyMediaElement.Position = TimeSpan.FromSeconds(seekSlider.Value);
            SetCurrentDuration();
        }

        // set duration of the opened file
        private void SetDuration()
        {
            string hour;
            string minute;
            string second;

            hour = (MyMediaElement.NaturalDuration.TimeSpan.Hours < 10) ? "0" + MyMediaElement.NaturalDuration.TimeSpan.Hours.ToString() : MyMediaElement.NaturalDuration.TimeSpan.Hours.ToString();
            minute = (MyMediaElement.NaturalDuration.TimeSpan.Minutes < 10) ? "0" + MyMediaElement.NaturalDuration.TimeSpan.Minutes.ToString() : MyMediaElement.NaturalDuration.TimeSpan.Minutes.ToString();
            second = (MyMediaElement.NaturalDuration.TimeSpan.Seconds < 10) ? "0" + MyMediaElement.NaturalDuration.TimeSpan.Seconds.ToString() : MyMediaElement.NaturalDuration.TimeSpan.Seconds.ToString();
            durationTimerTextBox.Text = hour + ":" + minute + ":" + second;           
        }

        // set current duration of file playing
        private void SetCurrentDuration()
        {
            if (isPlaying)
            {
                string hour;
                string minute;
                string second;

                hour = (MyMediaElement.Position.Hours < 10) ? "0" + MyMediaElement.Position.Hours.ToString() : MyMediaElement.Position.Hours.ToString();
                minute = (MyMediaElement.Position.Minutes < 10) ? "0" + MyMediaElement.Position.Minutes.ToString() : MyMediaElement.Position.Minutes.ToString();
                second = (MyMediaElement.Position.Seconds < 10) ? "0" + MyMediaElement.Position.Seconds.ToString() : MyMediaElement.Position.Seconds.ToString();

                curentDurationTextBox.Text = hour + ":" + minute + ":" + second;
            }
        }

        private void ResetDurationCounters()
        {
            curentDurationTextBox.Text = "00:00:00";
            durationTimerTextBox.Text = "00:00:00";
        }

        private void Fullscreen()
        {
            if (!isFullscreen)
            {
                TimeSpan fullscreenTime = MyMediaElement.Position;
                mediaPlayerHeight = MyMediaElement.Height;
                mediaPlayerWidth = MyMediaElement.Width;
                gridMediaPlayerBackground = gridMediaPlayer.Background;
                myMediaElementMargin = MyMediaElement.Margin;

                this.WindowStyle = WindowStyle.None;
                this.WindowState = WindowState.Maximized;
                mediaPlayerMenu.Visibility = Visibility.Hidden;
                MyMediaElement.Margin = this.Margin;
                gridMediaPlayer.Background = new SolidColorBrush(Colors.Black);             
                MyMediaElement.Position = fullscreenTime;
                durationTimerTextBox.Foreground = Brushes.White;
                curentDurationTextBox.Foreground = Brushes.White;
                volumeTextBox.Foreground = Brushes.White;
                HidePlayControls();
                isFullscreen = true;
               
            }
            else
            {
                TimeSpan fullscreenTime = MyMediaElement.Position;
                gridMediaPlayer.Background = gridMediaPlayerBackground;
                MyMediaElement.Margin = myMediaElementMargin;
                MyMediaElement.Height = mediaPlayerHeight;
                MyMediaElement.Width = mediaPlayerWidth;

                this.WindowStyle = WindowStyle.SingleBorderWindow;
                this.WindowState = WindowState.Normal;
                mediaPlayerMenu.Visibility = Visibility.Visible;
                MyMediaElement.Position = fullscreenTime;
                durationTimerTextBox.Foreground = Brushes.Black;
                curentDurationTextBox.Foreground = Brushes.Black;
                volumeTextBox.Foreground = Brushes.Black;
                ShowPlayControls();
                isFullscreen = false;
            }
        }

        private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.F)
            {
                Fullscreen();
            }

            if (isFullscreen)
            {
                if (e.Key == Key.Escape)
                {
                    Fullscreen();
                }
            }
        }

        // set mediaelement volume property 
        private void VolumeSliderDragCompleted(object sender, EventArgs e)
        {
            MyMediaElement.Volume = (double)volumeSlider.Value / 100;
            volumeTextBox.Text = ((int)volumeSlider.Value).ToString();
            isMuted = false;
        }

        private void muteButton_Click(object sender, RoutedEventArgs e)
        {
            Mute();
        }

        private void Mute()
        {
            if (!isMuted)
            {
                MyMediaElement.Volume = 0;
                volumeTextBox.Text = "00";
                isMuted = true;
            }
            else
            {
                MyMediaElement.Volume = (double)volumeSlider.Value / 100;
                volumeTextBox.Text = ((int)volumeSlider.Value).ToString();
                isMuted = false;
            }
        }

        // when file is opened set main window title to currently playing file name
        private void SetWindowTitle()
        {
            string sourceToParse = MyMediaElement.Source.ToString();
            char[] delimiter = { '/' };
            string[] source = sourceToParse.Split(delimiter);
            Window.Title = source[source.Length - 1];
        }

        // show play controls in full screen mode and start hide countdown
        private void ShowPlayControls()
        {
            if (isFullscreen)
            {
                hidePlayControlsTimer.Stop();

                MediaPlayerUserControl.Visibility = Visibility.Visible;
                curentDurationTextBox.Visibility = Visibility.Visible;
                durationTimerTextBox.Visibility = Visibility.Visible;
                seekSliderBorder.Visibility = Visibility.Visible;
                seekSlider.Visibility = Visibility.Visible;
                volumeTextBox.Visibility = Visibility.Visible;
                volumeSlider.Visibility = Visibility.Visible;
                volumeSliderBorder.Visibility = Visibility.Visible;
                muteButton.Visibility = Visibility.Visible;
            }

            if (isPlaying || isPaused)
            {
                hidePlayControlsTimer.Start();
            }
        }

        // hide play controls in full screen mode and stop hide countdown
        private void HidePlayControls()
        {
            if (isFullscreen)
            {
                MediaPlayerUserControl.Visibility = Visibility.Hidden;
                curentDurationTextBox.Visibility = Visibility.Hidden;
                durationTimerTextBox.Visibility = Visibility.Hidden;
                seekSliderBorder.Visibility = Visibility.Hidden;
                seekSlider.Visibility = Visibility.Hidden;
                volumeTextBox.Visibility = Visibility.Hidden;
                volumeSlider.Visibility = Visibility.Hidden;
                volumeSliderBorder.Visibility = Visibility.Hidden;
                muteButton.Visibility = Visibility.Hidden;
                HideMouseCursor();
               
                hidePlayControlsTimer.Stop();
            }
        }

        private void MyMediaElement_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            ShowMouseCursor();
            ShowPlayControls();
        }

        private void HideMouseCursor()
        {
            this.Cursor = Cursors.None;
        }

        private void ShowMouseCursor()
        {
            this.Cursor = Cursors.Arrow;
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            SaveSetings();
        }

        private void openFileFromMenu_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            OpenFile();
        }

        public void exitAppFromMenu_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            this.Close();
        }

        private void menuItemPlay_Click_1(object sender, RoutedEventArgs e)
        {
            Play();
        }

        private void menuItemPause_Click_1(object sender, RoutedEventArgs e)
        {
            Play();
        }

        private void menuItemStop_Click_1(object sender, RoutedEventArgs e)
        {
            Stop();
        }

        private void menuItemFullScreen_Click_1(object sender, RoutedEventArgs e)
        {
            Fullscreen();
        }

        private void openStream_Click_1(object sender, RoutedEventArgs e)
        {
            OpenUrlWindow();
        }

        private void menuItemOpenFile_Click_1(object sender, RoutedEventArgs e)
        {
            OpenFile();
        }

        private void menuItemOpenStream_Click_1(object sender, RoutedEventArgs e)
        {
            OpenUrlWindow();
        }
	}
}